package com.ruoyi.demo.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.demo.domain.HtWorkload;
import com.ruoyi.demo.domain.bo.HtWorkloadBo;
import com.ruoyi.demo.domain.vo.HtWorkHoursVo;
import com.ruoyi.demo.domain.vo.HtWorkloadVo;
import com.ruoyi.demo.mapper.HtWorkloadMapper;
import com.ruoyi.demo.service.IHtWorkloadService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

/**
 * 热处理工艺报Service业务层处理
 *
 * @author ruoyi
 * @date 2024-03-11
 */
@RequiredArgsConstructor
@Service
public class HtWorkloadServiceImpl implements IHtWorkloadService {

    private final HtWorkloadMapper baseMapper;

    /**
     * 查询热处理工艺报
     */
    @Override
    public HtWorkloadVo queryById(Long id){
        return baseMapper.selectVoById(id);
    }

    /**
     * 查询热处理工艺报
     */
    @Override
    public HtWorkloadVo queryByPartNumber(String partNumber){
        LambdaQueryWrapper<HtWorkload> lqw = Wrappers.lambdaQuery();
        lqw.eq(HtWorkload::getPartNumber, partNumber);
        return baseMapper.selectVoList(lqw).get(0);
    }

    /**
     * 查询热处理工艺报
     */
    @Override
    public List<HtWorkloadVo> queryByIds(Collection<Long> ids){
        return baseMapper.selectVoBatchIds(ids);
    }

    /**
     * 查询热处理工艺报列表
     */
    @Override
    public TableDataInfo<HtWorkloadVo> queryPageList(HtWorkloadBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<HtWorkload> lqw = buildQueryWrapper(bo);
        Page<HtWorkloadVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 查询热处理工艺报列表
     */
    @Override
    public List<HtWorkloadVo> queryList(HtWorkloadBo bo) {
        LambdaQueryWrapper<HtWorkload> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    /**
     * 导出热处理工艺报列表
     */
    @Override
    public Map<String, Object> exportStatistics(HtWorkloadBo bo) {
        Map<String, Object> map = new HashMap<>();
        LambdaQueryWrapper<HtWorkload> lqw = buildQueryWrapper(bo);
        List<HtWorkloadVo> list = baseMapper.selectVoList(lqw);

        // 获取当前年份和月份并进行格式化
        Calendar calendar = Calendar.getInstance();
        int year = calendar.get(Calendar.YEAR);
        int month = calendar.get(Calendar.MONTH) + 1;
        String date = year + "年" + month + "月";

        List<HtWorkloadVo> uniqueList = new ArrayList<>(list.stream()
                .collect(Collectors.toMap(
                        vo -> vo.getBaseNumber() + vo.getReleaseDate(), // 按baseNumber和releaseDate转换为组合key
                        vo -> vo, // 保留完整的HtWorkloadVo对象作为value
                        (existing, replacement) -> existing // 遇到重复的key时保留已有的对象
                ))
                .values());

        IntStream.range(0, uniqueList.size())
            .forEach(i -> {
                uniqueList.get(i).setOrder(i + 1);
                if (uniqueList.get(i).getFlag().equals("1")){
                    uniqueList.get(i).setFlag("锻件");
                }
            });
        map.put("total", uniqueList.size());
        map.put("date", date);

        Map<String, Object> multiListMap = new HashMap<>();
        multiListMap.put("map", map);
        multiListMap.put("data", uniqueList);
        return multiListMap;
    }

    /**
     * 查询热处理工时报列表
     */
    @Override
    public List<HtWorkHoursVo> exportWorkHours(HtWorkloadBo bo) {
        LambdaQueryWrapper<HtWorkload> lqw = buildQueryWrapper(bo);
        List<HtWorkloadVo> volist = baseMapper.selectVoList(lqw);

        //获得产品数不重复集合，热处理和锻造分开保留
        List<HtWorkloadVo> craftDistinctList = new ArrayList<>(volist.stream()
            .collect(Collectors.toMap(vo -> vo.getBaseNumber() + "-" + vo.getFlag() + "-" + vo.getCraftsMan(),
                vo -> vo,
                (existing, replacement) -> existing))
            .values());

        List<HtWorkloadVo> proofDistinctList = new ArrayList<>(volist.stream()
            .collect(Collectors.toMap(vo -> vo.getBaseNumber() + "-" + vo.getFlag() + "-" + vo.getProofReader(),
                vo -> vo,
                (existing, replacement) -> existing))
            .values());


        List<HtWorkHoursVo> resultList = new ArrayList<>();
        Set<String> uniqueCraftsManSet = new HashSet<>();

        //工艺员合集
        for (HtWorkloadVo vo : volist) {
            if (StringUtils.isNotBlank(vo.getCraftsMan())) {
                uniqueCraftsManSet.add(vo.getCraftsMan());
            }
        }

        for (String craftsMan : uniqueCraftsManSet) {
            HtWorkHoursVo workHoursVo = new HtWorkHoursVo();
            workHoursVo.setCraftsMan(craftsMan);
            resultList.add(workHoursVo);
        }

        //每个热处理工艺追个统计数量
        for (HtWorkHoursVo workHoursVo : resultList) {

            // 在这里可以访问每个workHoursVo对象
            //编制件数分组
            Map<String, Long> countMap1 = volist.stream()
                .filter(vo -> workHoursVo.getCraftsMan().equals(vo.getCraftsMan()))  // 替换"指定的craftsMan"为你所需要的craftsMan名
                .collect(Collectors.groupingBy(vo -> vo.getFlag().isEmpty() ? "热处理件数" : "锻件件数", Collectors.counting()));
            Long num1 = countMap1.get("热处理件数");
            workHoursVo.setHPartTotal(num1);
            Long num2 = countMap1.get("锻件件数");
            workHoursVo.setFPartTotal(num2);

            //校对件数分组
            Map<String, Long> countMap2 = volist.stream()
                .filter(vo -> workHoursVo.getCraftsMan().equals(vo.getProofReader()))  // 替换"指定的craftsMan"为你所需要的craftsMan名
                .collect(Collectors.groupingBy(vo -> vo.getFlag().isEmpty() ? "热处理校对件数" : "锻件校对件数", Collectors.counting()));
            Long num3 = countMap2.get("热处理校对件数");
            workHoursVo.setHCHKDPartTotal(num3);
            Long num4 = countMap2.get("锻件校对件数");
            workHoursVo.setFCHKDPartTotal(num4);

            // 在这里可以访问每个workHoursVo对象
            //编制产品数分组
            Map<String, Long> countMap3 = craftDistinctList.stream()
                .filter(vo -> workHoursVo.getCraftsMan().equals(vo.getCraftsMan()))  // 替换"指定的craftsMan"为你所需要的craftsMan名
                .collect(Collectors.groupingBy(vo -> vo.getFlag().isEmpty()? "热处理产品数" : "锻件产品数", Collectors.counting()));
            Long num5 = countMap3.get("热处理产品数");
            workHoursVo.setHBaseTotal(num5);
            Long num6 = countMap3.get("锻件产品数");
            workHoursVo.setFBaseTotal(num6);

            //校对产品数分组
            Map<String, Long> countMap4 = proofDistinctList.stream()
                .filter(vo -> workHoursVo.getCraftsMan().equals(vo.getProofReader()))  // 替换"指定的craftsMan"为你所需要的craftsMan名
                .collect(Collectors.groupingBy(vo -> vo.getFlag().isEmpty() ? "热处理校对产品数" : "锻件校对产品数", Collectors.counting()));
            Long num7 = countMap4.get("热处理校对产品数");
            workHoursVo.setHCHKDBaseTotal(num7);
            Long num8 = countMap4.get("锻件校对产品数");
            workHoursVo.setFCHKDBaseTotal(num8);

            Long workHours = (long) (((num5+num6)*0.5 + (num1+num7+num8)/6 + num2/3 + num3/18 + num4/9)*4);
            workHoursVo.setWorkHours(workHours);
        }


        return resultList;
    }

    private LambdaQueryWrapper<HtWorkload> buildQueryWrapper(HtWorkloadBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<HtWorkload> lqw = Wrappers.lambdaQuery();
        lqw.like(StringUtils.isNotBlank(bo.getPartNumber()), HtWorkload::getPartNumber, bo.getPartNumber());
        lqw.like(StringUtils.isNotBlank(bo.getBaseNumber()), HtWorkload::getBaseNumber, bo.getBaseNumber());
        lqw.like(StringUtils.isNotBlank(bo.getName()), HtWorkload::getName, bo.getName());
        lqw.eq(StringUtils.isNotBlank(bo.getCraftsMan()), HtWorkload::getCraftsMan, bo.getCraftsMan());
        lqw.eq(bo.getCraftsDate() != null, HtWorkload::getCraftsDate, bo.getCraftsDate());
        lqw.eq(StringUtils.isNotBlank(bo.getProofReader()), HtWorkload::getProofReader, bo.getProofReader());
        lqw.eq(bo.getProofDate() != null, HtWorkload::getProofDate, bo.getProofDate());
        lqw.between(params.get("beginPlanDate") != null && params.get("endPlanDate") != null,
            HtWorkload::getPlanDate ,params.get("beginPlanDate"), params.get("endPlanDate"));
        lqw.eq(StringUtils.isNotBlank(bo.getRoute()), HtWorkload::getRoute, bo.getRoute());
        lqw.eq(bo.getReleaseDate() != null, HtWorkload::getReleaseDate, bo.getReleaseDate());
        lqw.eq(bo.getFlag() != null, HtWorkload::getFlag, bo.getFlag());
        return lqw;
    }

    /**
     * 新增热处理工艺报
     */
    @Override
    public Boolean insertByBo(HtWorkloadBo bo) {
        HtWorkload add = BeanUtil.toBean(bo, HtWorkload.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setId(add.getId());
        }
        return flag;
    }

    /**
     * 修改热处理工艺报
     */
    @Override
    public Boolean updateByBo(HtWorkloadBo bo) {
        HtWorkload update = BeanUtil.toBean(bo, HtWorkload.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(HtWorkload entity){
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 批量删除热处理工艺报
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if(isValid){
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }
}
